package ar.com.ctrln.view.dashboard.calendar;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import org.zkoss.calendar.Calendars;
import org.zkoss.calendar.api.CalendarEvent;
import org.zkoss.calendar.event.CalendarsEvent;
import org.zkoss.calendar.impl.SimpleCalendarModel;
import org.zkoss.spring.security.SecurityUtil;
import org.zkoss.util.Locales;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.ForwardEvent;
import org.zkoss.zk.ui.metainfo.ComponentInfo;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Button;
import org.zkoss.zul.Label;
import org.zkoss.zul.Popup;
import org.zkoss.zul.Timer;
import org.zkoss.zul.Window;

import ar.com.ctrln.control.calendar.ConsultarEventos;
import ar.com.ctrln.persistence.model.evento.EventoCalendario;
import ar.com.ctrln.persistence.model.sistema.cuentas.Autorizacion;

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class CalendarioController extends SelectorComposer<Component> {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8790712549492943534L;

	@WireVariable
	private ConsultarEventos consultarEventos;

	@Wire
	private Window wCalendar;

	@Wire
	private Calendars wCalendario;

	private SimpleCalendarModel simpleCalendarModel = new SimpleCalendarModel();

	@Wire
	private Popup updateMsg;

	@Wire
	private Label popupLabel;

	@Wire
	private Timer timer;

	@Wire
	private Label label;

	@Wire
	private Button btnHoy;

	@Wire
	private Button nextPage;

	@Wire
	private Button prevPage;

	@Wire
	private Button btnDia;

	@Wire
	private Button btnSemana;

	@Wire
	private Button btn5Dias;

	@Wire
	private Button btnMes;

	TimeZone timeZone;

	@Override
	public ComponentInfo doBeforeCompose(Page page, Component parent,
			ComponentInfo compInfo) {

		if (wCalendar != null && simpleCalendarModel != null) {
			if (simpleCalendarModel.size() > 0) {
				simpleCalendarModel.clear();
				wCalendario.setModel(simpleCalendarModel);
				cargarEventosCalendario();
			}

		}

		return super.doBeforeCompose(page, parent, compInfo);
	}

	@Override
	public void doAfterCompose(Component comp) throws Exception {

		super.doAfterCompose(comp);
		timeZone = wCalendario.getDefaultTimeZone();
		wCalendario.setModel(simpleCalendarModel);
		cargarEventosCalendario();
	}

	private void syncModel() {
		@SuppressWarnings("unchecked")
		List<SimpleCalendarModel> list = simpleCalendarModel.get(
				wCalendario.getBeginDate(), wCalendario.getEndDate(), null);
		@SuppressWarnings("unused")
		double red = 0, blue = 0, green = 0, purple = 0, khaki = 0;
		@SuppressWarnings("unused")
		int size = list.size();
		for (@SuppressWarnings("rawtypes")
		Iterator it = list.iterator(); it.hasNext();) {
			String color = ((CalendarEvent) it.next()).getContentColor();
			if ("#D96666".equals(color))
				red += 1;
			else if ("#668CD9".equals(color))
				blue += 1;
			else if ("#4CB052".equals(color))
				green += 1;
			else if ("#B373B3".equals(color))
				purple += 1;
			else
				khaki += 1;
		}

	}

	public void cargarEventosCalendario() {
		@SuppressWarnings("unchecked")
		List<Autorizacion> autorizaciones = (List<Autorizacion>) SecurityUtil
				.getAuthentication().getAuthorities();
		Set<EventoCalendario> eventos = new HashSet<EventoCalendario>();

		for (Autorizacion autorizacion : autorizaciones) {

			eventos.addAll(consultarEventos.listarAutorizados(autorizacion
					.getId()));
		}
		if (eventos != null && !eventos.isEmpty()) {

			for (EventoCalendario eventoCalendario : eventos) {
				simpleCalendarModel.add(eventoCalendario);

			}
		}

	}

	@Listen("onEventUpdate = #wCalendario")
	public void updateEvent(CalendarsEvent event) {
		EventoCalendario data = (EventoCalendario) event.getCalendarEvent();
		SimpleDateFormat formatDate = new SimpleDateFormat("dd-MMM-yyyy");

		formatDate.setTimeZone(wCalendario.getDefaultTimeZone());

		StringBuffer sb = new StringBuffer("Actualizando... desde ");

		sb.append(formatDate.format(data.getBeginDate()));
		sb.append(" hasta ");

		sb.append(formatDate.format(event.getBeginDate()));

		popupLabel.setValue(sb.toString());

		int left = event.getX();
		int top = event.getY();
		if (top + 100 > event.getDesktopHeight())
			top = event.getDesktopHeight() - 100;
		if (left + 330 > event.getDesktopWidth())
			left = event.getDesktopWidth() - 330;
		updateMsg.open(left, top);
		timer.start();

		data.setBeginDate(event.getBeginDate());
		data.setEndDate(event.getEndDate());
		simpleCalendarModel.update(data);
	}

	@Listen("onEventCreate = #wCalendario")
	public void nuevoEvento(CalendarsEvent event) {

		CalendarsEvent calendarsEvent = event;

		event.stopClearGhost();

		Date fechaInicio = calendarsEvent.getBeginDate();
		Date fechaFin = calendarsEvent.getEndDate();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("desde", fechaInicio);
		map.put("hasta", fechaFin);
		map.put("CalendarsEvent", calendarsEvent);
		map.put("wCalendario", wCalendario);
		

		wCalendar.setAttribute("desde", fechaInicio);
		wCalendar.setAttribute("hasta", fechaFin);
		wCalendar.setAttribute("CalendarsEvent", calendarsEvent);
		wCalendar.setAttribute("wCalendario", wCalendario);

		Executions.createComponents(
				"/zul/calendar/registrarEventoCalendar.zul", wCalendar, null);

	}

	@Listen("onEventEdit = #wCalendario")
	public void editEvento(CalendarsEvent event) {
		CalendarsEvent calendarsEvent = event;

		event.stopClearGhost();

		EventoCalendario evento = (EventoCalendario) calendarsEvent
				.getCalendarEvent();

		Map<String, Object> map = new HashMap<String, Object>();

		map.put("EventoCalendario", evento);

		map.put("wCalendario", wCalendario);
		Executions.getCurrent().getSession()
				.setAttribute("consultarEvento", map);
		
		wCalendar.setAttribute("wCalendario", wCalendario);
		wCalendar.setAttribute("EventoCalendario", evento);

		Executions.createComponents("/zul/calendar/consultarEvento.zul",
				wCalendar, null);
	}

	public void onMoveDate(ForwardEvent event) {
		if ("arrow-left".equals(event.getData()))
			wCalendario.previousPage();
		else
			wCalendario.nextPage();
		updateDateLabel();
		syncModel();
	}

	@Listen("onClick = #btnDia")
	public void actualizarVistaDia() {
		wCalendario.setMold("default");
		wCalendario.setDays(1);
		updateDateLabel();
	}

	@Listen("onClick = #btn5Dias")
	public void actualizarVista5Dias() {
		wCalendario.setMold("default");
		wCalendario.setDays(5);
		updateDateLabel();
	}

	@Listen("onClick = #btnSemana")
	public void actualizarVistaSemana() {
		wCalendario.setMold("default");
		wCalendario.setDays(7);
		updateDateLabel();
	}

	@Listen("onClick = #btnMes")
	public void actualizarVistaMes() {
		wCalendario.setMold("month");
		updateDateLabel();
	}

	public void onUpdateView(ForwardEvent event) {
		String text = String.valueOf(event.getData());
		int days = "Dia".equals(text) ? 1 : "5 Dias".equals(text) ? 5
				: "Semana".equals(text) ? 7 : 0;

		if (days > 0) {
			wCalendario.setMold("default");
			wCalendario.setDays(days);
		} else
			wCalendario.setMold("month");
		updateDateLabel();
	}

	private void updateDateLabel() {
		Date b = wCalendario.getBeginDate();
		Date e = wCalendario.getEndDate();
		SimpleDateFormat sdfV = new SimpleDateFormat("dd-MMM-yyyy",
				Locales.getCurrent());
		sdfV.setTimeZone(wCalendario.getDefaultTimeZone());
		label.setValue(sdfV.format(b) + " - " + sdfV.format(e));
	}

	@Listen("onClick = #btnHoy")
	public void onToday() {
		wCalendario.setCurrentDate(Calendar.getInstance(
				wCalendario.getDefaultTimeZone()).getTime());
		updateDateLabel();
		syncModel();
	}

	@Listen("onClick = #prevPage")
	public void Siguiente() {
		wCalendario.previousPage();
		updateDateLabel();
		syncModel();
	}

	@Listen("onClick = #nextPage")
	public void Anterior() {
		wCalendario.nextPage();
		updateDateLabel();
		syncModel();
	}

	public void search(String search) {

	}

}